const useStorage = ($storage: Storage) => {
  const timeSign = '|-door-|';
  const timeSignLength = timeSign.length;
  /**
   * 根据 key 值移除储存在 storage 中的值
   * @param key storage key
   */
  const remove = (key: string) => $storage.removeItem(key);

  /**
   * 根据 key 值获取储存在 storage 中的值
   * @param key storage key
   */
  const get = (key: string) => {
    let value: any = $storage.getItem(key);
    if (value) {
      const index = value.indexOf(timeSign);
      if (index > -1) { // 存在过期时间标识
        const time = +value.slice(0, index);
        if (time > new Date().getTime() || time === 0) {
          value = value.slice(index + timeSignLength);
          try {
            value = JSON.parse(value);
          } catch {
            return value;
          }
        } else {
          value = null;
          remove(key);
        }
      } else {
        try {
          value = JSON.parse(value);
        } catch {
          return value;
        }
      }
    }
    return value;
  };

  /**
   *
   * @param key storage key
   * @param value 需要储存在 storage 中的值
   */
  /**
   * @description: 根据 key 值向 storage 中储存值
   * @param {string} key storage key
   * @param {any} value 需要储存在 storage 中的值
   * @param {Date} time 过期时间，默认31天 传过期时间的时间戳
   * @return {*}
   */
  const set = (key: string, value: any, time?: number) => {
    // 设置失效时间，未设置时间默认为一个月
    let _time = new Date().getTime() + 1000 * 60 * 60 * 24 * 31;
    if (time) {
      _time = new Date(time).getTime();
    }

    $storage.setItem(key, value ? `${_time}${timeSign}${JSON.stringify(value)}` : value);
  };

  /**
   * 移除除了 key 之外的所有储存在 storage 中的值
   * @param key storage key
   */
  const clearExcept = (key: string) => {
    for (let i = 0; i < $storage.length; i++) {
      const itemKey: any = $storage.key(i);
      if (itemKey && itemKey !== key) {
        $storage.removeItem(itemKey);
      }
    }
  };

  /**
   * 移除所有储存在 storage 中的值
   */
  const clear = () => {
    for (const itemKey in $storage) {
      if (itemKey) {
        $storage.removeItem(itemKey);
      }
    }
  };

  /**
   * @description: 清除storage中过期的内容
   * @return {*}
   */
  const clearExpired = () => {
    for (const key in $storage) {
      if (Object.prototype.hasOwnProperty.call($storage, key)) {
        get(key);
      }
    }
  };

  return {
    get,
    set,
    remove,
    clearExcept,
    clear,
    clearExpired,
  };
};

const SessionStorageService = useStorage(window.sessionStorage || sessionStorage);
const LocalStorageService = useStorage(window.localStorage || localStorage);

export {
  SessionStorageService,
  LocalStorageService,
};
